home *** CD-ROM | disk | FTP | other *** search
/ Aminet 23 / Aminet 23 (1998)(GTI - Schatztruhe)[!][Feb 1998].iso / Aminet / misc / emu / amiSPIMsrc.lha / cl-cache.c < prev    next >
C/C++ Source or Header  |  1993-05-17  |  21KB  |  923 lines

  1. /* SPIM S20 MIPS Cycle Level simulator.
  2.    Definitions for the SPIM S20 Cycle Level Simulator (SPIM-CL).
  3.    Copyright (C) 1991-1992 by Anne Rogers (amr@cs.princeton.edu) and
  4.    Scott Rosenberg (scottr@cs.princeton.edu)
  5.    ALL RIGHTS RESERVED.
  6.  
  7.    SPIM-CL is distributed under the following conditions:
  8.  
  9.      You may make copies of SPIM-CL for your own use and modify those copies.
  10.  
  11.      All copies of SPIM-CL must retain our names and copyright notice.
  12.  
  13.      You may not sell SPIM-CL or distributed SPIM-CL in conjunction with a
  14.      commerical product or service without the expressed written consent of
  15.      Anne Rogers.
  16.  
  17.    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  18.    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  19.    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20.    PURPOSE.
  21. */
  22.  
  23. /* Simple write through cache -- stall on all misses                 */
  24. /* Split transaction bus simulator                                   */
  25.  
  26. #include <stdio.h>
  27. #include <setjmp.h>
  28.  
  29. #include "spim.h"
  30. #include "inst.h"
  31. #include "mem.h"
  32. #include "mips-syscall.h"
  33. #include "cl-cache.h"
  34. #include "cl-mem.h"
  35. #include "cl-tlb.h"
  36.  
  37. #define TRUE 1
  38. #define FALSE 0
  39.  
  40. #define MEM_TO_CPU 0
  41. #define CPU_TO_MEM 1
  42.  
  43. #define CLEAR 0
  44. #define READY 1
  45. #define PENDING 2
  46. #define WRITE_BLOCKED 3
  47.  
  48. #define DCRB 1
  49. #define DCWB 2
  50. #define ICRB 3
  51.  
  52.  
  53. /* Exported Variables: */
  54.  
  55. MEM_SYSTEM mem_system;
  56. int dcache_modified, icache_modified;
  57. int line_size;
  58. int dcache_on, icache_on;
  59.  
  60.  
  61. extern jmp_buf spim_top_level_env;
  62.  
  63.  
  64. /* Local functions for bus */
  65.  
  66. #ifdef __STDC__
  67. static int arbitrate (MEM_SYSTEM mem_system);
  68. static int service_request(MEM_SYSTEM);
  69. static void rb_insert (MEM_SYSTEM mem_system, mem_addr addr, unsigned int
  70.                *req_num);
  71. static void ib_insert (MEM_SYSTEM mem_system, mem_addr addr, unsigned int
  72.                *req_num);
  73. static int wb_insert (MEM_SYSTEM mem_system, mem_addr addr, unsigned int
  74.               *req_num);
  75. static int wb_conflict (MEM_SYSTEM mem_system, mem_addr addr);
  76. static unsigned int wb_promote (MEM_SYSTEM mem_system);
  77. static void cache_update (CACHE cache, mem_addr addr, int type);
  78. #else
  79. static int arbitrate ();
  80. static int service_request ();
  81. static void rb_insert ();
  82. static void ib_insert ();
  83. static int wb_insert ();
  84. static int wb_conflict ();
  85. static unsigned int wb_promote ();
  86. static void cache_update ();
  87. #endif
  88.  
  89.  
  90. /* Macros */
  91. #define cache_line(addr)     ((addr) >> line_size_bits)
  92. #define cache_loc(cache,line,type)                    \
  93.   (line % (type == DATA_CACHE ? dcache_size : icache_size))
  94. #define mem_module(addr)     (cache_line(addr) % interleaving)
  95. #define is_mem_available(i,mem) (mem[i].available < 0)
  96. #define page_num(addr)         (addr >> 14)
  97. #define status_str(status)     ((status == CLEAR) ? "C" :         \
  98.                  ((status == PENDING) ? "P" :  \
  99.                   ((status == READY) ? "R" : "W")))
  100.  
  101.  
  102. /* general memory stats */
  103. int interleaving;            /* memory interleave factor */
  104. #define MEM_LAT     9             /* memory latency, usually 9 */
  105. #define PAGE_MEM_LAT    2        /* memory module page latency */
  106. #define WB_DEPTH     6               /* write buffer depth */
  107. #define BUS_LINE     (line_size/4)   /* time to move cache line on bus */
  108. #define BUS_ADDR    1        /* time to move address to mem */
  109. #define BUS_WORD    1        /* time to move word from mem */
  110.  
  111.  
  112. /* cache stats */
  113. /* note: variables tagged with "_bits" must change with their */
  114. /* corresponding "_size" variables */
  115. int line_size, line_size_bits;        /* line size for BOTH caches */
  116. int dcache_size, dcache_size_bits;
  117. int icache_size, icache_size_bits;
  118. int dcache_modified, icache_modified;    /* used by xspim to note change */
  119. int icache_on, dcache_on;
  120.  
  121.  
  122. static int last_req_num = 0;            /* last request number handed out */
  123. unsigned int statistics[10];             /* fields explained below */
  124.  
  125.  
  126. MEM_SYSTEM mem_system;
  127.  
  128.  
  129. #ifdef __STDC__
  130. void
  131. cache_wt_init (void)
  132. #else
  133. void
  134. cache_wt_init ()
  135. #endif
  136. {
  137.   interleaving = 1;
  138.  
  139.   dcache_size = 512;
  140.   dcache_size_bits = 9;
  141.   icache_size = 512;
  142.   icache_size_bits = 9;
  143.  
  144.   line_size = 32;
  145.   line_size_bits = 5;
  146. }
  147.  
  148.  
  149.  
  150.  
  151. /* Statistics stuff */
  152.  
  153.  
  154.  
  155. #define page_hit(kind) (statistics[kind]++)
  156. /* statistics[0] = page_hit(LOAD) */
  157. /* statistics[1] = page_hit(STORE) */
  158. /* statistics[2] = page_hit(ILOAD) */
  159.  
  160. #define hit(kind) (statistics[kind+3]++)
  161. /* statistics[3] = cache hit(LOAD)   */
  162. /* statistics[4] = cache hit(STORE)  */
  163. /* statistics[5] = cache hit(ILOAD)  */
  164.  
  165. #define miss(kind) (statistics[kind+6]++)
  166. /* statistics[6] = cache miss(LOAD)  */
  167. /* statistics[7] = cache miss(STORE) */
  168. /* statistics[8] = cache miss(ILOAD) */
  169.  
  170. #define write_blocked() (statistics[9]++)
  171. /* statistics[9] = write blocked     */
  172.  
  173.  
  174.  
  175. #ifdef __STDC__
  176. void
  177. stat_init (void)
  178. #else
  179. void
  180. stat_init ()
  181. #endif
  182. {
  183.   int i;
  184.  
  185.   for (i=0; i < 8; i++)
  186.     statistics[i] = 0;
  187. }
  188.  
  189.  
  190. #ifdef __STDC__
  191. void
  192. stat_print (void)
  193. #else
  194. void
  195. stat_print ()
  196. #endif
  197. {
  198.   printf("Data load hits:        %d\n", statistics[3]);
  199.   printf("          misses:      %d\n", statistics[6]);
  200.   printf("          page hits:   %d\n", statistics[0]);
  201.   printf("          page misses: %d\n", statistics[6]-statistics[0]);
  202.   printf("Inst load hits:        %d\n", statistics[5]);
  203.   printf("          misses:      %d\n", statistics[8]);
  204.   printf("          page hits:   %d\n", statistics[2]);
  205.   printf("          page misses: %d\n", statistics[8]-statistics[2]);
  206.   printf("Data Store hits:       %d\n", statistics[4]);
  207.   printf("          misses:      %d\n", statistics[7]);
  208.   printf("          page hits:   %d\n", statistics[1]);
  209.   printf("          page misses: %d\n", (statistics[4]+statistics[7])-
  210.          statistics[1]);
  211. }
  212.  
  213.  
  214.  
  215.  
  216. /* service the bus queues for 1 cycle at time t */
  217. /* Priority scheme...see arbitrate              */
  218.  
  219. #ifdef __STDC__
  220. unsigned
  221. int bus_service (MEM_SYSTEM mem_system)
  222. #else
  223. unsigned
  224. int bus_service (mem_system)
  225.   MEM_SYSTEM mem_system;
  226. #endif
  227. {
  228.   int i;
  229.   BUS bus;
  230.   MAIN_MEM main;
  231.   DCQ rb, wb, ib;
  232.   static unsigned finished_request = 0;     /* delay announcing finished
  233.                            request for 1 cycle */
  234.   unsigned int prev_finished_request = finished_request;
  235.  
  236.  
  237.   bus = mem_system->bus;
  238.   main = mem_system->main;
  239.   rb = mem_system->read_buffer;
  240.   wb = mem_system->write_buffer;
  241.   ib = mem_system->inst_buffer;
  242.  
  243.  
  244.   /* if bus is busy */
  245.   if (bus->busy > 1) {
  246.     bus->busy--;
  247.   }
  248.  
  249.   else if (bus->busy == 1) {
  250.     /* This request will finish in this cycle */
  251.  
  252.     /* read mem request */
  253.     if ((bus->direction == MEM_TO_CPU) && (bus->request == rb->req_num) &&
  254.     (rb->status == PENDING)) {
  255.       finished_request = bus->request;
  256.       cache_update (mem_system->dcache, rb->addr, DATA_CACHE);
  257.       rb->status = CLEAR;
  258.     }
  259.  
  260.     /* read inst request */
  261.     else if ((bus->direction == MEM_TO_CPU) &&
  262.          (bus->request == ib->req_num) && (ib->status == PENDING)) {
  263.       finished_request = bus->request;
  264.       cache_update (mem_system->icache, ib->addr, INST_CACHE);
  265.       ib->status = CLEAR;
  266.     }
  267.  
  268.     /* write request */
  269.     else if ((bus->direction == CPU_TO_MEM) &&
  270.          (bus->request == wb[0].req_num) && (wb[0].status == PENDING)) {
  271.       finished_request = wb_promote(mem_system);
  272.       if ((wb[0].status == CLEAR) && (rb->status == WRITE_BLOCKED))
  273.     rb->status = READY;
  274.     }
  275.     bus->busy--;
  276.   }
  277.  
  278.   else if ((bus->busy == 0) && (bus->arb_winner > 0)) {
  279.     service_request (mem_system);
  280.     bus->arb_winner = 0;
  281.     bus->busy = (bus->busy == 0) ? 0 : bus->busy-1;
  282.   }
  283.  
  284.   else {
  285.     /* arbitrate for next cycle */
  286.     bus->arb_winner = arbitrate(mem_system);
  287.   }
  288.  
  289.   /* update all of the mem_available times */
  290.   for (i = 0; i < interleaving; i++) {
  291.     if (main[i].available > 1)
  292.       main[i].available = main[i].available - 1;
  293.     else if (main[i].available == 1)
  294.       if (main[i].req_type == LOAD || main[i].req_type == ILOAD)
  295.     main[i].available = 0;
  296.       else main[i].available = -1;  /* Stores do not send a reply */
  297.     else /*do nothing */
  298.       ;
  299.   }
  300.  
  301.   return prev_finished_request;
  302. }
  303.  
  304.  
  305.  
  306.  
  307. #ifdef __STDC__
  308. static int
  309. arbitrate (MEM_SYSTEM mem_system)
  310. #else
  311. static int
  312. arbitrate (mem_system)
  313.   MEM_SYSTEM mem_system;
  314. #endif
  315. {
  316.   int i;
  317.   DCQ rb, wb, ib;
  318.  
  319.   rb = mem_system->read_buffer;
  320.   wb = mem_system->write_buffer;
  321.   ib = mem_system->inst_buffer;
  322.  
  323.   if ((rb->status == READY) &&
  324.       (is_mem_available (mem_system->main, mem_module(rb->addr))))
  325.     return DCRB;
  326.  
  327.   if ((ib->status == READY) &&
  328.       (is_mem_available (mem_system->main, mem_module(ib->addr))))
  329.     return ICRB;
  330.  
  331.   if ((wb[0].status == READY) &&
  332.       (is_mem_available (mem_system->main, mem_module(wb[0].addr))))
  333.     return DCWB;
  334.  
  335.   for (i=0; i < interleaving; i++)
  336.     if (mem_system->main[i].available == 0)
  337.       return i + 4;
  338.  
  339.   /* nothing ready */
  340.   return 0;
  341. }
  342.  
  343.  
  344.  
  345.  
  346. #ifdef __STDC__
  347. static int
  348. service_request (MEM_SYSTEM mem_system)
  349. #else
  350. static int
  351. service_request (mem_system)
  352.   MEM_SYSTEM mem_system;
  353. #endif
  354. {
  355.   BUS bus = mem_system->bus;
  356.   MAIN_MEM main = mem_system->main;
  357.   DCQ rb = mem_system->read_buffer;
  358.   DCQ wb = mem_system->write_buffer;
  359.   DCQ ib = mem_system->inst_buffer;
  360.  
  361.   switch (bus->arb_winner) {
  362.   case DCRB:
  363.     /* service read request */
  364.     bus->module = mem_module(rb->addr);
  365.     bus->busy = BUS_ADDR;
  366.     bus->request = rb->req_num;
  367.     bus->direction = CPU_TO_MEM;
  368.  
  369.     if (page_num(rb->addr) == main[bus->module].last_page) {
  370.       page_hit(LOAD);
  371.       main[bus->module].available =  BUS_ADDR + PAGE_MEM_LAT;
  372.     }
  373.     else {
  374.       main[bus->module].available =  BUS_ADDR + MEM_LAT;
  375.       main[bus->module].last_page = page_num(rb->addr);
  376.     }
  377.     main[bus->module].req_type = LOAD;
  378.     main[bus->module].req_number = rb->req_num;
  379.  
  380.     rb->status = PENDING;
  381.     return 0;
  382.  
  383.   case ICRB:
  384.     /* service read inst request */
  385.     bus->module = mem_module(ib->addr);
  386.     bus->busy = BUS_ADDR;
  387.     bus->request = ib->req_num;
  388.     bus->direction = CPU_TO_MEM;
  389.  
  390.     if (page_num(ib->addr) == main[bus->module].last_page) {
  391.       page_hit(ILOAD);
  392.       main[bus->module].available =  BUS_ADDR + PAGE_MEM_LAT;
  393.     }
  394.     else {
  395.       main[bus->module].available =  BUS_ADDR + MEM_LAT;
  396.       main[bus->module].last_page = page_num(ib->addr);
  397.     }
  398.     main[bus->module].req_type = ILOAD;
  399.     main[bus->module].req_number = ib->req_num;
  400.  
  401.     ib->status = PENDING;
  402.     return 0;
  403.  
  404.  
  405.   case DCWB:
  406.     {
  407.       /* service write buffer */
  408.       bus->module = mem_module(wb[0].addr);
  409.       bus->busy = BUS_ADDR + BUS_WORD;
  410.       bus->request = wb[0].req_num;
  411.       bus->direction = CPU_TO_MEM;
  412.  
  413.       if (page_num(wb[0].addr) == main[bus->module].last_page) {
  414.     page_hit(STORE);
  415.     main[bus->module].available = BUS_ADDR + BUS_WORD + PAGE_MEM_LAT;
  416.       }
  417.       else {
  418.     main[bus->module].available = BUS_ADDR + BUS_WORD + MEM_LAT;
  419.     main[bus->module].last_page = page_num(wb[0].addr);
  420.       }
  421.       main[bus->module].req_type = STORE;
  422.       wb[0].status = PENDING;
  423.       return 0;
  424.     }
  425.  
  426.   default:
  427.     bus->module = bus->arb_winner - 4;
  428.     if ((bus->module >= 0) && (bus->module < interleaving)) {
  429.       /* sevice memory reply -- must be LOAD or ILOAD request */
  430.       bus->busy = BUS_LINE;
  431.       bus->request = main[bus->module].req_number;
  432.       bus->direction = MEM_TO_CPU;
  433.  
  434.       /* memory module is now available */
  435.       main[bus->module].available = -1;
  436.       return 0;
  437.     }
  438.  
  439.     else {
  440.       printf("Error in service request -- %d \n", bus->arb_winner);
  441.       exit(1);
  442.     }
  443.  
  444.   }
  445.  
  446. }
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453. /* Read buffer insert */
  454. #ifdef __STDC__
  455. static void
  456. rb_insert (MEM_SYSTEM mem_system, mem_addr addr, unsigned int *req_num)
  457. #else
  458. static void
  459. rb_insert (mem_system, addr, req_num)
  460.   MEM_SYSTEM mem_system;
  461.   mem_addr addr;
  462.   unsigned int *req_num;
  463. #endif
  464. {
  465.   *req_num = ++last_req_num;
  466.  
  467.   mem_system->read_buffer->addr = addr;
  468.   if (wb_conflict(mem_system, addr)) {
  469.     write_blocked();
  470.     mem_system->read_buffer->status = WRITE_BLOCKED;
  471.   }
  472.   else
  473.     mem_system->read_buffer->status = READY;
  474.   mem_system->read_buffer->req_num = *req_num;
  475. }
  476.  
  477.  
  478. /* Inst buffer insert */
  479. #ifdef __STDC__
  480. static void
  481. ib_insert (MEM_SYSTEM mem_system, mem_addr addr, unsigned int *req_num)
  482. #else
  483. static void
  484. ib_insert (mem_system, addr, req_num)
  485.   MEM_SYSTEM mem_system;
  486.   mem_addr addr;
  487.   unsigned int *req_num;
  488. #endif
  489. {
  490.   *req_num = ++last_req_num;
  491.  
  492.   mem_system->inst_buffer->addr = addr;
  493.   mem_system->inst_buffer->status = READY;
  494.   mem_system->inst_buffer->req_num = *req_num;
  495. }
  496.  
  497.  
  498.  
  499. /* Write buffer insert */
  500. #ifdef __STDC__
  501. static int
  502. wb_insert (MEM_SYSTEM mem_system, mem_addr addr, unsigned int *req_num)
  503. #else
  504. static int
  505. wb_insert (mem_system, addr, req_num)
  506.   MEM_SYSTEM mem_system;
  507.   mem_addr addr;
  508.   unsigned int *req_num;
  509. #endif
  510. {
  511.   int i;
  512.  
  513.   for (i=0; i < WB_DEPTH; i++)
  514.     /* find an open slot in the write buffer */
  515.     if (mem_system->write_buffer[i].status == CLEAR) {
  516.       mem_system->write_buffer[i].addr = addr;
  517.       mem_system->write_buffer[i].status = READY;
  518.       return TRUE;
  519.     }
  520.  
  521.   /* only need a request number if we have to block because
  522.      there is no more room in the write_buffer */
  523.   *req_num = ++last_req_num;
  524.   mem_system->write_buffer[WB_DEPTH].addr = addr;
  525.   mem_system->write_buffer[WB_DEPTH].status = READY;
  526.   mem_system->write_buffer[WB_DEPTH].req_num = *req_num;
  527.   return FALSE;
  528. }
  529.  
  530.  
  531. /* Is there a pending write to addr's cache line in the write buffer */
  532. #ifdef __STDC__
  533. static int
  534. wb_conflict (MEM_SYSTEM mem_system, mem_addr addr)
  535. #else
  536. static int
  537. wb_conflict (mem_system, addr)
  538.   MEM_SYSTEM mem_system;
  539.   mem_addr addr;
  540. #endif
  541. {
  542.   int i;
  543.  
  544.   for (i=0; i < WB_DEPTH; i++)
  545.     if ((cache_line(addr) == cache_line(mem_system->write_buffer[i].addr))
  546.     && (mem_system->write_buffer[i].status != CLEAR))
  547.       return TRUE;
  548.  
  549.   return FALSE;
  550. }
  551.  
  552.  
  553. #ifdef __STDC__
  554. static unsigned int
  555. wb_promote (MEM_SYSTEM mem_system)
  556. #else
  557. static unsigned int
  558. wb_promote (mem_system)
  559.   MEM_SYSTEM mem_system;
  560. #endif
  561. {
  562.   int i;
  563.  
  564.   for (i = 1; i <= WB_DEPTH; i++)
  565.     mem_system->write_buffer[i-1] = mem_system->write_buffer[i];
  566.  
  567.   mem_system->write_buffer[WB_DEPTH].status = CLEAR;
  568.  
  569.   if (mem_system->write_buffer[WB_DEPTH-1].status == READY)
  570.     /* would have been write_blocked return request num to
  571.        signal that stall is finished */
  572.     return mem_system->write_buffer[WB_DEPTH-1].req_num;
  573.   else return 0;
  574. }
  575.  
  576.  
  577.  
  578.  
  579. #ifdef __STDC__
  580. MEM_SYSTEM
  581. mem_sys_init (void)
  582. #else
  583. MEM_SYSTEM
  584. mem_sys_init ()
  585. #endif
  586. {
  587.   int i;
  588.   MEM_SYSTEM mem_system;
  589.  
  590.   mem_system = (MEM_SYSTEM) malloc(sizeof(struct mem_sys));
  591.   mem_system->bus = (BUS) malloc(sizeof(struct bus_desc));
  592.   mem_system->read_buffer = (DCQ) malloc(sizeof(struct dcq));
  593.   mem_system->write_buffer = (DCQ) malloc(sizeof(struct dcq)*(WB_DEPTH+1));
  594.   mem_system->inst_buffer = (DCQ) malloc(sizeof(struct dcq));
  595.  
  596.   mem_system->bus->arb_winner = 0;
  597.   mem_system->bus->busy = 0;
  598.  
  599.   mem_system->read_buffer->status = CLEAR;
  600.   mem_system->inst_buffer->status = CLEAR;
  601.   for (i=0; i <= WB_DEPTH; i++)
  602.     mem_system->write_buffer[i].status = CLEAR;
  603.  
  604.   for (i=0; i < interleaving; i++) {
  605.     mem_system->main[i].available = -1;
  606.     mem_system->main[i].last_page = -1;
  607.   }
  608.  
  609.   stat_init();
  610.  
  611.   /* default cache specs for cycle level spim */
  612.   cache_wt_init ();
  613.   cache_init (mem_system, INST_CACHE);
  614.   cache_init (mem_system, DATA_CACHE);
  615.  
  616.   return mem_system;
  617. }
  618.  
  619.  
  620.  
  621. #ifdef __STDC__
  622. void
  623. print_mem_sys_status (int finished, MEM_SYSTEM mem_system)
  624. #else
  625. void
  626. print_mem_sys_status (finished, mem_system)
  627.   int finished;
  628.   MEM_SYSTEM mem_system;
  629. #endif
  630. {
  631.   int i;
  632.   BUS bus = mem_system->bus;
  633.   MAIN_MEM main = mem_system->main;
  634.   DCQ rb = mem_system->read_buffer;
  635.   DCQ wb = mem_system->write_buffer;
  636.   DCQ ib = mem_system->inst_buffer;
  637.  
  638.  
  639.   printf("Finished request = %x\n", finished);
  640.   printf("bus->busy = %d, bus->arb_winner = %d\n", bus->busy, bus->arb_winner);
  641.   printf("direction = %s, request = %d\n\n",
  642.      (bus->direction == CPU_TO_MEM) ? "CPU_TO_MEM" : "MEM_TO_CPU",
  643.      bus->request);
  644.  
  645.   printf("DCRB -- addr = %x, status = %s, module = %d, req_num = %d\n",
  646.      rb->addr, status_str(rb->status), mem_module(rb->addr),
  647.      rb->req_num);
  648.   printf("ICRB -- addr = %x, status = %s, module = %d, req_num = %d\n",
  649.      ib->addr, status_str(ib->status), mem_module(ib->addr),
  650.      ib->req_num);
  651.  
  652.   for (i = 0; i <= WB_DEPTH; i++) {
  653.     if (wb[i].status == CLEAR)
  654.       break;
  655.     printf("DCWB[%d] -- addr = %x, status = %s, module = %d \n",
  656.        i,
  657.        wb[i].addr,
  658.        status_str(wb[i].status),
  659.        mem_module(wb[i].addr));
  660.   }
  661.   printf("\n");
  662.  
  663.  
  664.   printf("Memory -- \n");
  665.   printf("    ");
  666.   for (i=0; i < interleaving; i++)
  667.     printf("%d ", main[i].available);
  668.   printf("\n");
  669.  
  670.   printf("    ");
  671.   for (i=0; i < interleaving; i++)
  672.     printf("%s ", (main[i].req_type == LOAD) ? "L" :
  673.        ((main[i].req_type == ILOAD) ? "IL" : "S"));
  674.   printf("\n");
  675.  
  676.   printf("    ");
  677.   for (i=0; i < interleaving; i++)
  678.     printf("%d ", main[i].req_number);
  679.   printf("\n\n");
  680.  
  681. }
  682.  
  683.  
  684.  
  685. /* ============================================================================== */
  686.  
  687. /* Direct mapped, physically addressed cache, write through caches */
  688. /* Anne Rogers                              */
  689. /* 18 June 91                               */
  690.  
  691.  
  692. #define is_valid(state)  ((state) & 1)
  693. #define set_valid(state)  ((state) = 1)
  694. #define set_invalid(state)  ((state) = 0)
  695.  
  696. #ifdef __STDC__
  697. void
  698. cache_init (MEM_SYSTEM mem_system, int type)
  699. #else
  700. void
  701. cache_init (mem_system, type)
  702.   MEM_SYSTEM mem_system;
  703.   int type;
  704. #endif
  705. {
  706.   int i;
  707.  
  708.   switch (type) {
  709.   case DATA_CACHE:
  710.     for(i=0; i < MAX_CACHE_SIZE; i++)
  711.       mem_system->dcache[i].state = 0;
  712.     break;
  713.   case INST_CACHE:
  714.     for(i=0; i < MAX_CACHE_SIZE; i++)
  715.       mem_system->icache[i].state = 0;
  716.     break;
  717.   }
  718. }
  719.  
  720.  
  721.  
  722. #ifdef __STDC__
  723. int
  724. cache_service (MEM_SYSTEM mem_system, mem_addr addr, int type, unsigned int
  725.            *req_num)
  726. #else
  727. int
  728. cache_service (mem_system, addr, type, req_num)
  729.   MEM_SYSTEM mem_system;
  730.   mem_addr addr;
  731.   int type;
  732.   unsigned int *req_num;
  733. #endif
  734. {
  735.   int line, loc;
  736.  
  737.   switch (type) {
  738.  
  739.   case (STORE):
  740.     if (!dcache_on) return CACHE_HIT;
  741.     if (wb_insert(mem_system, addr, req_num)) {
  742.       hit(STORE);
  743.       return CACHE_HIT;
  744.     }
  745.     else {
  746.       miss(STORE);
  747.       return CACHE_MISS;
  748.     }
  749.     break;
  750.  
  751.   case (LOAD):
  752.     if (!dcache_on) return CACHE_HIT;
  753.     line = cache_line (addr);
  754.     loc = cache_loc (mem_system->dcache, line, DATA_CACHE);
  755.  
  756.     if ((mem_system->dcache[loc].block_num == line) &&
  757.     (is_valid(mem_system->dcache[loc].state))) {
  758.       hit(LOAD);
  759.       return CACHE_HIT;
  760.     }
  761.     else {
  762.       miss(LOAD);
  763.       rb_insert(mem_system, addr, req_num);
  764.       return CACHE_MISS;
  765.     }
  766.     break;
  767.  
  768.   case (ILOAD):
  769.     if (!icache_on) return CACHE_HIT;
  770.     line = cache_line (addr);
  771.     loc = cache_loc (mem_system->icache, line, INST_CACHE);
  772.  
  773.     if ((mem_system->icache[loc].block_num == line) &&
  774.     (is_valid (mem_system->icache[loc].state))) {
  775.       hit(ILOAD);
  776.       return CACHE_HIT;
  777.     }
  778.     else {
  779.       miss(ILOAD);
  780.       ib_insert(mem_system, addr, req_num);
  781.       return CACHE_MISS;
  782.     }
  783.     break;
  784.  
  785.   }
  786. }
  787.  
  788.  
  789.  
  790.  
  791. #ifdef __STDC__
  792. static void
  793. cache_update (CACHE cache, mem_addr addr, int type)
  794. #else
  795. static void
  796. cache_update (cache, addr, type)
  797.   CACHE cache;
  798.   mem_addr addr;
  799.   int type;
  800. #endif
  801. {
  802.   int loc, line;
  803.  
  804.   line = cache_line (addr);
  805.   loc = cache_loc (cache, line, type);
  806.   cache[loc].block_num = line;
  807.   set_valid(cache[loc].state);
  808.  
  809.   if (type == DATA_CACHE)
  810.     dcache_modified = 1;
  811.   else
  812.     icache_modified = 1;
  813. }
  814.  
  815.  
  816. #ifdef __STDC__
  817. int
  818. cache_probe (CACHE cache, mem_addr addr, int type)
  819. #else
  820. int
  821. cache_probe (cache, addr, type)
  822.   CACHE cache;
  823.   mem_addr addr;
  824.   int type;
  825. #endif
  826. {
  827.   int line, loc;
  828.  
  829.   line = cache_line(addr);
  830.   loc = cache_loc(cache, line, type);
  831.  
  832.   if ((cache[loc].block_num == line) && (is_valid(cache[loc].state)))
  833.     return CACHE_HIT;
  834.   else return CACHE_MISS;
  835. }
  836.  
  837.  
  838.  
  839. /* ============================================================================= */
  840. /* Auxilliary Routines                                                           */
  841.  
  842. #ifdef __STDC__
  843. void
  844. print_cache_stats (char *buf, int type)
  845. #else
  846. void
  847. print_cache_stats (buf, type)
  848.   char *buf;
  849.   int type;
  850. #endif
  851. {
  852.   switch (type) {
  853.   case DATA_CACHE:
  854.     sprintf (buf, "%d lines; %d bytes/line\n", dcache_size, line_size);
  855.     buf += strlen(buf);
  856.     break;
  857.   case INST_CACHE:
  858.     sprintf (buf, "%d lines; %d bytes/line\n", icache_size, line_size);
  859.     buf += strlen(buf);
  860.     break;
  861.   }
  862.   sprintf (buf, "   LINE   VALID    TAG\n");
  863. }
  864.  
  865.  
  866. #ifdef __STDC__
  867. void
  868. print_cache_data (char *buf, int type)
  869. #else
  870. void
  871. print_cache_data (buf, type)
  872.   char *buf;
  873.   int type;
  874. #endif
  875. {
  876.   int x, size, size_bits;
  877.   struct cache_entry *cache;
  878.  
  879.  
  880.   if (type == DATA_CACHE) {
  881.     cache = mem_system->dcache;
  882.     size = dcache_size;
  883.     size_bits = dcache_size_bits;
  884.   }
  885.   else {
  886.     cache = mem_system->icache;
  887.     size = icache_size;
  888.     size_bits = icache_size_bits;
  889.   }
  890.  
  891.   for (x = 0; x < size; x++)
  892.     {
  893.       /* print index, valid, and real tag field */
  894.       sprintf (buf, "%4d      %1d   0x%08x   ", x, is_valid(cache[x].state),
  895.            ((cache[x].block_num >> size_bits)
  896.         << (size_bits + line_size_bits)));
  897.       buf += strlen(buf);
  898.       *(buf++) = '\n';
  899.     }
  900.   *buf = '\0';
  901. }
  902.  
  903.  
  904. #ifdef __STDC__
  905. char *
  906. print_write_buffer (void)
  907. #else
  908. char *
  909. print_write_buffer ()
  910. #endif
  911. {
  912.   int x;
  913.   static char str[256];
  914.   char *buf = str;
  915.  
  916.   for (x=0; x<WB_DEPTH; x++) {
  917.     sprintf (buf, "0x%08x ", *(int*)(mem_system->write_buffer + x*sizeof(DCQ)));
  918.     buf += strlen(buf);
  919.   }
  920.   return str;
  921. }
  922.  
  923.